"""
Author: Jian SuiYue kaohx0214@yeah.net
Date: 2025-05-05 02:13:09
LastEditTime: 2025-05-15 17:09:15
FilePath: LibraryManagerStudio/web/routes/friend_api.py
"""
from fastapi import APIRouter, Depends, HTTPException, status, Query
from fastapi.responses import JSONResponse

from .token_api import validate_jwt
from ..deps import get_db
from ...database import DBManager
from ...datamodel import User, Friend, FriendBase, FriendUpdate

router = APIRouter()


@router.get("/get")
async def get_friends_by_uid(
        login: str = Query(...),
        user_id: str = Query(..., ge=1),
        db: DBManager = Depends(get_db)
):
    """
    get_friends_by_uid

    GET /get?login={your_token}&user_id={your_user_id}
    Args:
        login: Token.id
        user_id: User.id
        db: DBManager
    """
    validate_jwt(login)
    # check user exist
    user_exist = db.get(User, filters={"id": user_id})
    if not user_exist.data or not user_exist.status:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"User ID {user_id} not found")

    result = db.get(Friend, filters={"uid": user_id})
    if not result.data or not result.status:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,
                            detail=f"Unexpected Error at get friends by uid: {user_id}")

    return JSONResponse(
        status_code=status.HTTP_200_OK,
        content={"status": True, "data": result.data, "message": "Get friend list successful"}
    )


@router.post("/gets")
async def get_friends(
        login: str = Query(...),
        page: int = Query(..., ge=1),
        size: int = Query(..., ge=1, le=100),
        db: DBManager = Depends(get_db)
):
    """
    get_friends

    POST /gets?login={your_token}&page={page}&size={size}
    Args:
        token: Token.id
        pageinfo: Pageinfo(page: int, size: int)
        db: DBManager
    """
    validate_jwt(login)
    result = db.get(Friend, page_info={"page": page, "size": size})
    if not result.data or not result.status:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=f"Unexpected Error at get friend list")

    return JSONResponse(
        status_code=status.HTTP_200_OK,
        content={"status": True, "data": result.data, "message": "Get friend list successful"}
    )


@router.post("/new")
async def new_friend(
        friend_base: FriendBase,
        login: str = Query(...),
        db: DBManager = Depends(get_db)
):
    """
    Create a new friend relationship
    
    POST /new?login={your_token}
    Args:
        friend_base: FriendBase
        login: Token.id
        db: DBManager
    """
    validate_jwt(login)

    uid, friend_uid = friend_base.uid, friend_base.friend_uid

    # verify user exist
    user_exist = db.get(User, filters={"id": uid})
    if not user_exist.status or not user_exist.data:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"User ID {uid} Not found")

    # verify friend exist
    friend_exist = db.get(User, filters={"id": friend_uid})
    if not friend_exist.status or not friend_exist.data:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Friend User ID {friend_uid} Not found")

    # Check if friend_base relationship already exists
    existing_friend = db.get(Friend, filters={"uid": uid, "friend_uid": friend_uid})
    if existing_friend.status and existing_friend.data:
        raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=f"Friend relationship already exists")

    # Create friend_base relationship
    friend = Friend(uid=friend_base.uid, friend_uid=friend_base.friend_uid, status=friend_base.status)
    result = db.upsert(friend)
    if not result.status or not result.data:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,
                            detail=f"Unexpected error at creating friend relationship")

    return JSONResponse(
        status_code=status.HTTP_200_OK,
        content={"status": True, "data": result.data[0], "message": "Friend relationship created successfully"}
    )


@router.put("/update")
async def update_friend(
        friend: FriendUpdate,
        login: str = Query(...),
        db: DBManager = Depends(get_db)
):
    """
    Update a friend relationship

    PUT /update?login={your_token}
    Args:
        login: Token.id
        friend: Friend
        db: DBManager
    """
    # 检查好友关系是否存在
    validate_jwt(login)

    # verify user exist
    user_exist = db.get(User, filters={"id": friend.uid})
    if not user_exist.status or not user_exist.data:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"User ID {friend.uid} not found")

    # verify friend exist
    friend_user_exist = db.get(User, filters={"id": friend.friend_uid})
    if not friend_user_exist.status or not friend_user_exist.data:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
                            detail=f"Friend User ID {friend.friend_uid} not found")

    # verify relationship exist
    existing_friend = db.get(Friend, filters={"uid": friend.uid, "friend_uid": friend.friend_uid})
    if not existing_friend.status or not existing_friend.data:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Friend relationship not found")

    # Update friend relationship
    origin = existing_friend.data[0]
    origin["status"] = friend.status
    response = db.upsert(Friend(**origin))
    if not response.status:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=f"Unexpected Error: {response.message}")

    return JSONResponse(
        status_code=status.HTTP_200_OK,
        content={"status": True, "message": "Friend relationship updated successfully"}
    )


@router.delete("/delete")
async def delete_friend(
        login: str = Query(...),
        uid: int = Query(..., ge=1),
        friend_uid: int = Query(..., ge=1),
        db: DBManager = Depends(get_db)
):
    """
    Delete a friend relationship
    
    DELETE /delete?login={your_token}&friend_id={friend_id}
    Args:
        login: Token.id
        uid: User.id
        friend_uid: User.id
        db: DBManager
    """
    validate_jwt(login)
    # verify user exist
    user_exist = db.get(User, filters={"id": uid})
    if not user_exist.status or not user_exist.data:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"User ID {uid} not found")

    # verify friend exist
    friend_user_exist = db.get(User, filters={"id": friend_uid})
    if not friend_user_exist.status or not friend_user_exist.data:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Friend User ID {friend_uid} not found")

    # verify relationship exist
    existing_friend = db.get(Friend, filters={"uid": uid, "friend_uid": friend_uid})
    if not existing_friend.status or not existing_friend.data:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Friend relationship not found")

    result = db.delete(Friend, filters={"uid": uid, "friend_uid": friend_uid})
    if not result.status or not result.data:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=f"Unexpected Error: {result.message}")

    return JSONResponse(
        status_code=status.HTTP_200_OK,
        content={"status": True, "message": "Friend relationship deleted successfully"}
    )
